

package net.sourceforge.jsorter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import net.sourceforge.jsorter.SortReflect.MethodException;


/**
 *
 * @author  Jason Rutherglen
 */
public class SortHolder<T> implements Comparable {
  public Comparable attribute;
  public T object;
  public int nullBehavior = SorterConstants.NULLS_ARE_INVALID;
  
  public SortHolder(Comparable attribute, T object, int nullBehavior) {
    this.attribute = attribute;
    this.object = object;
    this.nullBehavior = nullBehavior;
  }
  
  public String toString() {
    if (attribute == null) return "null";
    return attribute.toString();
  }
  
  public static List getTable(SortReflect[] sortReflect, Collection collection, int nullBehavior) throws MethodException {
    List table = new ArrayList(collection.size());
    Iterator iterator = collection.iterator();
    while (iterator.hasNext()) {
      Object value = iterator.next();
      List row = new ArrayList(sortReflect.length); 
      for (int x=0; x < sortReflect.length; x++) {
        Object attribute = sortReflect[x].get(value);
        if (attribute instanceof java.net.URL) {
          attribute = ((java.net.URL)attribute).toString();
        }
        Comparable attributeComparable = (Comparable)attribute;
        SortHolder sortHolder = new SortHolder(attributeComparable, value, nullBehavior);
        row.add(sortHolder);
      }
      table.add(row);
    }
    return table;
  }
  
  public int compareTo(Object obj) {
    Comparable comparableOne = (Comparable)attribute;
    Comparable comparableTwo = (Comparable)obj;
    if (obj instanceof SortHolder) {
      SortHolder sortHolder = (SortHolder)obj;
      comparableTwo = (Comparable)sortHolder.attribute;
    }
    
    int rtn;
    
    if (comparableOne != null && comparableTwo != null) {
      try {
        rtn = comparableOne.compareTo(comparableTwo);
      } catch (ClassCastException exception) {
        throw exception;
      }
    } else {
      if (nullBehavior == SorterConstants.NULLS_ARE_INVALID) {
        throw new IllegalStateException("Null data values are not valid.");
      } else if (comparableOne == null && comparableTwo != null) {
        rtn = -1;
        
        if (nullBehavior == SorterConstants.NULLS_ARE_GREATEST) {
          rtn = rtn * -1;
        }
      } else if (comparableOne != null && comparableTwo == null) {
        rtn = 1;
        
        if (nullBehavior == SorterConstants.NULLS_ARE_GREATEST) {
          rtn = rtn * -1;
        }
      } else {
        rtn = 0;
      }
    }
    return rtn;
  }
}
